package org.wheel.quartz;

import org.quartz.JobExecutionContext;
import org.quartz.impl.JobExecutionContextImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.function.Function;

/**
 * job 执行器
 */
public class JobExecutor {

    private Logger logger;
    private Method method;
    private Object instance;
    private Function<JobExecutionContext, Object[]> jobExecutionContextFunction;

    public JobExecutor(Method method, Object instance, Function<JobExecutionContext, Object[]> jobExecutionContextFunction) {
        this.instance = instance;
        this.init(this.method = method);
        this.jobExecutionContextFunction = jobExecutionContextFunction;
    }

    protected void init(Method method) {
        this.logger = LoggerFactory.getLogger(String.format("%s.%s", method.getDeclaringClass()
                .getName().split("\\$\\$")[0], method.getName()));
    }

    /**
     * 执行并记录日志
     *
     * @param context
     */
    public void execute(JobExecutionContext context) {
        String desc = context.getJobDetail().getDescription();
        if (logger.isDebugEnabled()) {
            logger.debug(String.format("开始运行【%s】", desc));
        }
        try {
            ReflectionUtils.invokeMethod(this.method, this.instance
                    , this.jobExecutionContextFunction.apply(context));
            if (logger.isDebugEnabled()) {
                logger.debug(String.format("【%s】运行成功, 运行时间 %s 秒", desc
                        , (System.currentTimeMillis() - context.getFireTime().getTime()) / 1000));
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            context.setResult(e.getMessage());
        }
        ((JobExecutionContextImpl) context).setJobRunTime(System.currentTimeMillis());
    }
}
